To make good looking Vue apps, we need to style our components.
To make our lives easier, we can use components with styles built-in.
In this article, we look at how to create dynamic tabs.
Also, we look at how to add a time picker to our app.
Dynamic Tabs
We can add tabs to a page dynamically.
For instance, we can write:
<template>
<div id="app">
<b-tabs>
<b-tab v-for="(i, index) in tabs" :key="i" :title="`Tab ${i}`">
<div class="p-3">
Tab {{ i }}
<b-button @click="closeTab(index)">Close tab</b-button>
</div>
</b-tab>
<template v-slot:tabs-end>
<b-nav-item @click.prevent="newTab" href="#">
<b>+</b>
</b-nav-item>
</template>
</b-tabs>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
tabs: []
};
},
methods: {
newTab() {
this.tabs = [...this.tabs, this.tabs.length + 1];
},
closeTab(index) {
this.tabs.splice(index, 1);
}
}
};
</script>
We populate the tabs-end slot with a b-nav-item component to let us display a link to let users add a new tab.
To add a new tab, the newTab method is called to add a new tab.
It just adds a new number to tabs .
The tabs are rendered by looping through tabs and render them as b-tab components.
To remove a tab, we have the closeTab method to remove an entry by index with splice .
Then the updated set of tabs will be rendered.
Time
We can display a time picker with the b-time component.
For example, we can write:
<template>
<div id="app">
<b-time v-model="value" locale="en" @context="onContext"></b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
},
methods: {
onContext(ctx) {
console.log(ctx)
}
}
};
</script>
We added the b-time component which displays a time picker.
The selected time is bound to the value state via v-model .
locale is set as 'en' to set the locale to English.
onContext is called when a time component selected.
The ctx parameter is an object with the formatted time, locale, and time parts.
Disabled
We can make it non-interactive by setting the disabled prop:
<template>
<div id="app">
<b-time v-model="value" disabled></b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
}
};
</script>
Read-Only
We can make it focusable but prevent the user from selecting a time with the readonly prop:
<template>
<div id="app">
<b-time v-model="value" readonly></b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
}
};
</script>
Styling
There are various ways we can style a time component.
Enable the Seconds Spin Button
We can add the show-seconds prop to show the seconds spin button.
It’s not shown by default.
For example, we can write:
<template>
<div id="app">
<b-time v-model="value" show-seconds></b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
}
};
</script>
Hiding the Top Selected Time Header
The hide-header prop will hide the selected time:
<template>
<div id="app">
<b-time v-model="value" hide-header></b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
}
};
</script>
Border and Padding
We can add the class prop to apply styles we want:
<template>
<div id="app">
<b-time v-model="value" class="border rounded p-2"></b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
}
};
</script>
Default Slot
The default slot lets us add content to the bottom of the time picker.
For example, we can write:
<template>
<div id="app">
<b-time v-model="value" class="border rounded p-2">
<b-button variant="outline-danger" @click="value = ''">Clear time</b-button>
</b-time>
<p>{{value}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: ""
};
}
};
</script>
We added a b-button to the default slot to reset value to an empty string.
Conclusion
We can make tabs dynamic by rendering b-tab with v-for .
Also, BootstrapVue comes with a time picker that we can let the user select a time.